package com.cndw.kungfu.model.scene;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Component;

import com.cndw.commons.util.BlankUtils;
import com.cndw.commons.util.DateFormatUtils;
import com.cndw.kungfu.comm.tencent.QQDC;
import com.cndw.kungfu.config.Constants;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsModel;
import com.cndw.kungfu.config.ConstantsRadio;
import com.cndw.kungfu.domain.Npc;
import com.cndw.kungfu.domain.Pendant;
import com.cndw.kungfu.domain.Player;
import com.cndw.kungfu.domain.Scene;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataStaticCenter;
import com.cndw.kungfu.model.activity.ModeSceneWall;
import com.cndw.kungfu.model.goods.PlayerTrade;
import com.cndw.kungfu.model.pve.UnionPet;
import com.cndw.kungfu.model.pve.UnionPetBattle;
import com.cndw.kungfu.model.pvp.camp.CampWar;
import com.cndw.kungfu.model.siege.domain.SiegeWar;
import com.cndw.kungfu.vo.EventNotice;
import com.cndw.rpg.framework.Session;
import com.cndw.rpg.framework.SessionHolder;

/**
 * 场景管理器 兼 副本管理器
 * 
 * @author fantadust
 * @date 2011-5-5 上午10:38:04
 */
@Component
public class SceneServer {

	/**
	 * 获取某个npc,并提交map
	 * 
	 * @param id
	 * @return
	 */
	public Npc getNpcById(int id) {
		return Context.getCacheCenter().getNpcById(id);
	}

	public Pendant getpPendant(int id) {
		return Context.getCacheCenter().getPendant(id);
	}

	/**
	 * 获取场景对象
	 * 
	 * @param sceneId
	 * @return
	 */
	public Scene getSceneById(int sceneId) {
		return Context.getCacheCenter().getSceneById(sceneId);

	}

	public List<Npc> getNpcBySceneId(int sceneId) {
		List<Npc> npcs = new ArrayList<Npc>();
		for (Npc npc : Context.getCacheCenter().getAllNpcs()) {
			if (npc.getSceneId() == sceneId) {
				npcs.add(npc);
			}
		}
		return npcs;
	}

	/**
	 * 离开场景
	 * 
	 * @param session
	 * @param enterScene
	 */
	public void exitScene(Session session, Scene enterScene) {
		long playerId = session.getUid();

		Player player = Context.getPlayerServer().getByPlayerId(playerId);

		if (player.getSceneId() == 0) {
			return;
		}
		Scene lastScene = Context.getSceneServer().getSceneById(player.getSceneId());
		if (lastScene == null) {
			return;

		}
		lastScene.removePlayerId(playerId, player.getSubLine());// 从场景记录里面删除

		String idKey = Context.getSceneServer().getRadioKey(player.getSceneId(), player.getSubLine());
		Context.getTcpServer().removeGroup(session, idKey);

		lastScene.broadcast(player, playerId, ConstantsRadio.sceneExit);

		if (lastScene.isCityWall()) {// 从塞外退出，移除状态
			if (enterScene == null || enterScene.isCityWall() == false) {
				ModeSceneWall.removePlayer(player);
				player.setSceneId(player.getDataInfo().getLastSceneId());// 设置上次场景id
				player.setX(0);
				player.setY(0);
			}
		} else if (lastScene.isCityUnionWar()) {//从秘境退出
			SiegeWar.noPlayer(playerId);
		} else if (lastScene.isSpecialBroadcast()) {//从帮派神兽退出
			UnionPetBattle.getInstance().removePlayer(player.getUnionId(), playerId);
		}

		if (player.getTs() > 0 && player.getTx() > 0 && player.getTy() > 0) {
			player.setX(player.getTx());
			player.setY(player.getTy());
		} else if (enterScene != null) {
			int x = player.getX();
			int y = player.getY();
			int xOffset = enterScene.isCityMain() ? 200 : 0;
			boolean change = true;
			if (enterScene.getId() == lastScene.getId()) {
				change = false;
			} else if (enterScene.getRightScene() == lastScene.getId()) {
				x = enterScene.getBirthPoint()[2] + NumberProcesser.mtRand(-150 - xOffset, -50);
				y = enterScene.getBirthPoint()[3] + NumberProcesser.mtRand(-100, 100);
			} else if (enterScene.getUpScene() == lastScene.getId()) {
				x = enterScene.getBirthPoint()[4] + NumberProcesser.mtRand(-100, 0);
				y = enterScene.getBirthPoint()[5] + NumberProcesser.mtRand(100);
			} else if (enterScene.getDownScene() == lastScene.getId()) {
				x = enterScene.getBirthPoint()[6] + NumberProcesser.mtRand(-100, 0);
				y = enterScene.getBirthPoint()[7] + NumberProcesser.mtRand(-100, 0);
			} else {
				x = enterScene.getBirthPoint()[0] + NumberProcesser.mtRand(150 + xOffset, 50);
				y = enterScene.getBirthPoint()[1] + NumberProcesser.mtRand(-100, 100);
			}
			if (change) {
				// System.out.println(x+"|"+y);
				if (x <= 0 || y <= 0) {
					x = 0;
					y = 0;
				}
				player.setX(x);
				player.setY(y);
			}

		}
		player.setTx(0);
		player.setTy(0);
		player.setTs(0);
		if (ConstantsConfig.isSysInspectMove()) {
			player.setTz(TimeProcesser.currentTimeMillis());
		}

	}

	/**
	 * 玩家下线时候执行
	 * 
	 * @param session
	 */
	public void offLine(Session session) {
		if (session.getUid() > 0) {
			try {
				long playerId = session.getUid();
				Player player = Context.getPlayerServer().getByPlayerId(playerId);

				// 设置离线时间和结算在线时间
				player.updateOffLineAndOnlineTime();

				player.setTx(0);
				player.setTy(0);

				// 领取在线经验（打坐）
				Context.getGeneralServer().getOnlineExp(player);

				// 如果在摆摊，收摊
				if (player.stateContains(Constants.playerState64_market)) {
					player.getDataInfo().closeMarket();
				}

				// 如果在交易，退出交易
				if (player.stateContains(Constants.playerState128_trade)) {
					PlayerTrade trade = Context.getDataServer().getPlayerTradeMap().get(player.getPlayerId());
					if (!BlankUtils.isBlank(trade)) {
						trade.canelTrade(LanguageLib.get("market.trade.offline"), player.getPlayerId());
					}
				}

				// 通知好友下线
				EventNotice eventNotice = new EventNotice("friend", "offline");
				eventNotice.put("playerId", player.getPlayerId());
				eventNotice.put("playerName", player.getPlayerName());
				eventNotice.broadcast(player.getDataInfo().getFriendIds());

				exitScene(session, null);// 离开场景
				player.setSubLine(0);

				Context.getUndercityServer().gcUndercity(player.getPlayerId());

				Scene scene = Context.getSceneServer().getSceneById(player.getSceneId());
				if (scene != null) {
					if (scene.isCityUndercity() || scene.isCityWall() || scene.isCityUnionWar() || scene.isSpecialBroadcast()) {
						player.setSceneId(player.getDataInfo().getLastSceneId());
						player.setX(0);
						player.setY(0);
					}
				}

				player.getDataInfo().setUndercityId(0);
				player.getDataInfo().setLastSceneId(0);// 清理掉上次场景id

				if (player.getTeam() != null) {// 下线离开队伍
					player.getTeam().memberRemove(player);
				}
				
				Context.getTaskServer().gcTaskProgress(player.getPlayerId());//回收任务进度不存在的东西
				
				player.stateRemove(Constants.playerState1_battle);
				player.stateRemove(Constants.playerState512_battleAuto);
				player.getDataInfo().setOpenPass(false);//下线锁定包裹

				player.commitSync();// 用队列同步用户数据
				player.getDataInfo().commitSync();

				/**
				 * 离线上报数据
				 */
				if (!player.getDataInfo().isGmLogin()) {
					QQDC.getInstance().logOut(player);
				}
				
				CampWar.logoutUid(playerId);//退出门派战
				
				DataStaticCenter.flashMJOpen(session.getUid(), false);

			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				SessionHolder.getInstance().remove(session.getUid(), session);
			}

		}
	}

	/**
	 * 返回广播用的地图key
	 * 
	 * @param sceneId
	 * @return
	 */
	public String getRadioKey(int sceneId, int subLine) {
		return "sceneRaido_" + sceneId + "_" + subLine;
	}

	/**
	 * 检查是否塞外玩法时间
	 * 
	 * @return
	 */
	public boolean checkIsWallTime() {
		Date current = DateFormatUtils.getDate();
		return current.after(getWallBeginTime()) && current.before(getWallEndTime());
	}

	/**
	 * 检查是否塞外刺杀时间
	 * 
	 * @return
	 */
	public boolean checkIsWallKillTime() {
		Date current = DateFormatUtils.getDate();
		return current.after(getWallBeginTime()) && current.before(TimeProcesser.getHourDateTime(ConstantsModel.wallTime[1]));
	}

	public Date getWallEndTime() {
		return TimeProcesser.getHourDateTime(ConstantsModel.wallTime[1]);
	}

	public Date getWallBeginTime() {
		return TimeProcesser.getHourDateTime(ConstantsModel.wallTime[0]);
	}

	public Collection<Long> getOnSceneIds(Player player,Scene scene) {
		if (scene.getId() == 66005 && player.getUnionId() > 0) {
			UnionPet unionPet = UnionPetBattle.getInstance().getUnionPet(player.getUnionId());
			if (unionPet != null) {
				return unionPet.getJoinIds();
			}
		}
		return null;
	}
}
